
static void hrtimer_update_softirq_timer(struct hrtimer_cpu_base *cpu_base, bool reprogram)
{
    ktime_t expires;

    /*
     * Find the next SOFT expiration.
     */
    expires = __hrtimer_get_next_event(cpu_base, HRTIMER_ACTIVE_SOFT);

    /*
     * reprogramming needs to be triggered, even if the next soft
     * hrtimer expires at the same time than the next hard
     * hrtimer. cpu_base->softirq_expires_next needs to be updated!
     */
    if (expires == KTIME_MAX)
        return;

    /*
     * cpu_base->*next_timer is recomputed by __hrtimer_get_next_event()
     * cpu_base->*expires_next is only set by hrtimer_reprogram()
     */
    hrtimer_reprogram(cpu_base->softirq_next_timer, reprogram);
}

static void hrtimer_run_softirq(void)
{
    struct hrtimer_cpu_base *cpu_base = this_cpu_ptr(&hrtimer_bases);
    unsigned long flags;
    ktime_t now;

    hrtimer_cpu_base_lock_expiry(cpu_base);
    raw_spin_lock_irqsave(&cpu_base->lock, flags);

    now = hrtimer_update_base(cpu_base);
    __hrtimer_run_queues(cpu_base, now, flags, HRTIMER_ACTIVE_SOFT);

    cpu_base->softirq_activated = 0;
    hrtimer_update_softirq_timer(cpu_base, true);

    raw_spin_unlock_irqrestore(&cpu_base->lock, flags);
    hrtimer_cpu_base_unlock_expiry(cpu_base);
}
